<?php
  session_start();
/**
 * Author: bedirhan
 * OWASP SQLiBENCH SoC 2008 Project
 * see SqliBench.php
 */  
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>OWASP SQLiBENCH Project Interactive Criteria Listing</title>
        <link href="style.css" rel="stylesheet" type="text/css"/>
    </head>
    <body>
    
        <table class="projectinfo">
            <tr>
                <td>
                    <a href="mailto:urgunb@hotmail.com">Bedirhan Urgun</a> & <a href="mailto:mesut_timur@hotmail.com">Mesut Timur</a>
                </td>
            </tr>
            <tr> 
                <td>       
                    <a href="http://www.owasp.org/index.php/Category:OWASP_Sqlibench_Project" target="_blank">owasp</a>
                    &nbsp;
                    <a href="http://code.google.com/p/sqlibench" target="_blank">google</a>
                </td>
            </tr>
            <tr>
                <td>
                    28 September 2008
                </td>
            </tr>
        </table>
    
        <h2>OWASP SQLiBENCH Project - Interactive Criteria Listing</h2>
        
        <form action="index.php" method="POST" name="sqlibenchform">
        
        <?php
            
            
            include "SqliBench.php";
            
            $sqlibenchObj = new SqliBench("sqlibench_data.xml");           
            
            // we'll dynamically create select boxes and store their
            // element names/ids in our session in order to get sent parameters
            // from the client
            $elementnames = array();
            $elementvalues = array();
            
            // get created names/ids from our session, if they exists
            if(isset($_SESSION['elementnames'])){
                $elementnames = &$_SESSION['elementnames'];
                $elementvalues = &$_SESSION['elementvalues'];
                
                // do some input validation
                foreach($elementnames as $elementname){
                    /*
                     * special XPath characters;
                     / . *  @ [ ] = : ( ) & ; | 
                     * an we allow the ones below;
                     / . ( ) -
                     * the problem is XPath Injection. What are the risks;
                     * 1. Data theft of sqlibench.xml is not a problem, however, 
                     * can attacker read files/access other resources by injection
                     * XPath?
                     * 2. A vulnerability exists in XPath parser in PHP and attacker
                     * triggers it leading to Remote Code Exec. Mitigation: Restrict
                     * the length of the input to 40.
                     * 3. ?
                     */
                    $preg = "/^[a-zA-Z\d\.\/\(\)\- ]{1,40}$/D" ;
                    if(isset($_POST[$elementname]) && !preg_match($preg, $_POST[$elementname])){
                        //echo "<h3>Input validation failed.".htmlEncode($_POST[$elementname])."</h3>";
                        echo "<h3>Input validation failed.</h3>";
                        exit;
                    }
                }
                
            }
            else{
                $_SESSION['elementnames'] = $elementnames;
                $_SESSION['elementvalues'] = $elementvalues;
                $elementnames = &$_SESSION['elementnames'];
                $elementvalues = &$_SESSION['elementvalues'];
            }
            
            $continue = TRUE;
            $propagate = TRUE;
            $levelIndex = 0;
            $labelPath = array();
            while($continue){
                // a variable is set at level $levelIndex
                if(isset($_POST[$elementnames[$levelIndex]]) && $propagate){
                    
                    $selectedLabel = $_POST[$elementnames[$levelIndex]];
                    
                    $selectedLabel = createSelect($sqlibenchObj, $labelPath, $levelIndex, $selectedLabel);
                                        
                    // if the value hasn't change, then create select as is
                    if(strcmp($selectedLabel, $elementvalues[$levelIndex]) == 0)
                      $propagate = TRUE;
                    else
                      $propagate = FALSE;
                    
                    // update the related value
                    $elementvalues[$levelIndex] = $selectedLabel;

                    if($selectedLabel == NULL) {
                        $continue = FALSE;
                        continue;
                    }

                    // update the labelPath after we've created the select box
                    // for this selected item
                    array_push($labelPath, $selectedLabel);
                    
                }
                else{
                    $selectedLabel = createSelect($sqlibenchObj, $labelPath, $levelIndex, NULL);
                    if($selectedLabel == NULL){
                        $continue = FALSE;
                        continue;
                    }
                    array_push($labelPath, $selectedLabel);
                    // store the newly created element name in the session. The name doesn't matter.
                    $elementnames[$levelIndex] = $levelIndex; 
                    $elementvalues[$levelIndex] = $selectedLabel; 
                }
                $levelIndex = $levelIndex + 1;
            }
            
            function createSelect($sqlibenchObj, $labelPath, $levelIndex, $selectedLabel){
                
                $labels = $sqlibenchObj->getLabels($labelPath);
                
                // the target element is a leaf, for which we don't create a
                // select element, we print it directly
                if(count($labels) == 0){
                    // let's try to find out whether the content is long explanation or a small one, 
                    // if a content starts with all uppercase EXP, then it's a long explanation
                    $res = strpos($sqlibenchObj->getContent($labelPath), "EXP");
                    if( $res !== FALSE && $res == 0){
                      // chop off the initial EXP
                      $str = substr($sqlibenchObj->getContent($labelPath), 3);
                      echo "<div class='longexplanation'>" . allowSomeHtmlOnly(htmlEncode($str)) . "</div>";
                    }
                    else{
                      // this is a normal standard short explanation
                      echo "<div class='shortexplanation'>" . allowSomeHtmlOnly(htmlEncode($sqlibenchObj->getContent($labelPath))) . "</div>";
                    }
                    return NULL;
                }
                
                if(!isset($selectedLabel))
                  $selectedLabel = $labels[0];
                
                $select = "<select size=7 name='$levelIndex' id='$levelIndex' onchange='forms.sqlibenchform.submit();'>";
                foreach($labels as $label){
                  if(strcmp($selectedLabel, $label) == 0)
                    $select .= "<option value='".htmlEncode($label)."' selected>".htmlEncode($label)."</option>";
                  else
                    $select .= "<option value='".htmlEncode($label)."'>".htmlEncode($label)."</option>";
                }                
                $select .= "</select>&nbsp;&nbsp;";
                
                echo $select;              
                                
                return $selectedLabel;
            }
            
            function htmlEncode($input)
            {
                return htmlentities($input, ENT_QUOTES, "UTF-8") ;
            }            
            
            function allowSomeHtmlOnly($input){
                $str = str_replace("&lt;br/&gt;", "<br/>", $input);
                $str = str_replace("&lt;ol&gt;", "<ol>", $str);
                $str = str_replace("&lt;/ol&gt;", "</ol>", $str);
                $str = str_replace("&lt;li&gt;", "<li>", $str);
                $str = str_replace("&lt;/li&gt;", "</li>", $str);                
                $str = str_replace("&lt;b&gt;", "<b>", $str);
                $str = str_replace("&lt;/b&gt;", "</b>", $str);
                return $str;
            }
            
        ?>
        <!-- <input type="submit" value="UPDATE"/> -->
        </form>
    </body>
</html>
